/*
 * Copyright (C) 2019 ByteDance Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.bytedance.scene.ui.view;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.Canvas;
import ohos.agp.utils.Color;
import ohos.agp.window.service.ComponentPadding;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.Resource;

import java.io.IOException;

/**
 * Created by JiangQi on 8/28/18.
 */
public final class NavigationBarView extends Component implements Component.DrawTask, Component.EstimateSizeListener {
    private ComponentPadding mLastInsets;
    private boolean mDrawNavigationBarBackground = true;
    private Element mNavigationBarBackground;

    public NavigationBarView(Context context) {
        super(context);
        init();
    }

    public NavigationBarView(Context context, AttrSet attrs) {
        super(context, attrs);
        init();
    }

    public NavigationBarView(Context context, AttrSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        addDrawTask(this);
        setEstimateSizeListener(this);
        if (mLastInsets == null) {
            mLastInsets = new ComponentPadding();
        }
    }

    public void setNavigationBarBackground(Element bg) {
        mNavigationBarBackground = bg;
        invalidate();
    }

    public Element getNavigationBarBackgroundDrawable() {
        return mNavigationBarBackground;
    }

    public void setNavigationBarBackground(int resId) {
        try {
            Resource resource = getResourceManager().getResource(resId);
            mNavigationBarBackground = resId != 0 ? new PixelMapElement(resource) : null;
        } catch (IOException | NotExistException e) {
            e.printStackTrace();
        }
        invalidate();
    }

    public void setNavigationBarBackgroundColor(int color) {
        mNavigationBarBackground = new ShapeElement(getContext(), new Color(color).getValue());
        invalidate();
    }

    private static int getDefaultSize2(int size, int measureSpec) {
        int result = 0;
        int specMode = EstimateSpec.getMode(measureSpec);
        int specSize = EstimateSpec.getSize(measureSpec);

        switch (specMode) {
            case EstimateSpec.UNCONSTRAINT:
                result = size;
                break;
            case EstimateSpec.NOT_EXCEED:
                result = Math.min(size, specSize);
                break;
            case EstimateSpec.PRECISE:
                result = specSize;
                break;
        }
        return result;
    }


    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (mDrawNavigationBarBackground && mNavigationBarBackground != null) {
            final int inset;
            inset = mLastInsets != null
                    ? mLastInsets.getSystemComponentPaddingBottom() : 0;
            if (inset > 0) {
                mNavigationBarBackground.setBounds(0, getHeight() - inset, getWidth(), getHeight());
                mNavigationBarBackground.drawToCanvas(canvas);
            }
        }
    }

    @Override
    public boolean onEstimateSize(int widthMeasureSpec, int heightMeasureSpec) {
        if (mLastInsets != null) {
            onMeasure2(widthMeasureSpec, EstimateSpec.getSizeWithMode(mLastInsets.getSystemComponentPaddingBottom(), EstimateSpec.PRECISE));
        } else {
            onMeasure2(widthMeasureSpec, heightMeasureSpec);
        }
        return false;
    }

    protected void onMeasure2(int widthMeasureSpec, int heightMeasureSpec) {
        setEstimatedSize(
                getDefaultSize2(getMinHeight(), widthMeasureSpec),
                getDefaultSize2(getMinHeight(), heightMeasureSpec));
    }
}
